Add Unicode property escape conversion for Script and Binary properties#34
Add Unicode property escape conversion for Script and Binary properties#34lahma wants to merge 1 commit into
Conversation
Previously, Acornima could validate \p{Script=Latin} and \p{Alphabetic}
property names but could not convert them to .NET Regex code point ranges,
causing a ConversionError. Only General Categories (e.g. \p{Lu}) were
convertible.
This adds static Unicode 17.0.0 code point range data for all Script,
Script_Extensions, and Binary properties recognized by ECMAScript, enabling
full regexp-unicode-property-escapes support.
Changes:
- UnicodeProperties.Generated.cs: Static code point range data for 175
scripts (sc/scx) and 50 binary properties, generated from Unicode 17.0.0
UCD files
- UnicodeProperties.cs: GetScriptRange, GetScriptExtensionsRange, and
GetBinaryPropertyRange methods with lazy caching. Special-case handling
for Any, ASCII, and Assigned
- CodePointRange.cs: Cache fields for script/binary property ranges
- Tokenizer.RegExpParser.Unicode.cs: Wire range lookups into
ValidateUnicodeProperty, split sc/Script from scx/Script_Extensions
- tools/UnicodeDataGenerator: Generator tool to parse UCD files and produce
the generated C# source
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Oh, some RegExp and Unicode, the two banes of my existence... 😅 Although this could be a nice addition, I'm not really fond of the idea of embedding a big chunk of Unicode data in a core parser library. (This is why only I think we need to take a step back here as I'm getting pretty convinced that this JS to .NET regexp conversion logic doesn't really belong in a parser library since it's about execution, not syntax. As a matter of fact, it's primarily for supporting Jint, so probably it'd belong there more (or, at least, in a separate package) if we consider responsibilities. I feel even more strongly about this when I think about the Unicode sets mode, which is the only main blocker of ES2024+ support now. Support for legacy Unicode mode (flag u) is quirky and limited but Unicode sets mode (flag v) is pretty much impossible to implement on top of the current .NET Regex engine. This is why I think it's not really worth putting additional significant effort in this approach, which will always be quirky, limited and fragile. Instead, something like this looks like the way forward:
At least, I don't really see another viable way of moving Acornima ahead and implementing Unicode sets in Jint. I can't make promises but I plan to make progress with steps 1-3 in the coming months because this "flag v" thing has been bugging me for way too long now 😅 |
|
Just to be clear: I'm not rejecting this PR, it's just on hold until the refactor I outlined above is done. |
|
Thanks for the feedback. I created this intentionally as draft as I was investigating how far I could go in fixing. So basically running Jint and Acornima sources together against failing tests.
Yes, this kind of porting is exactly suited for AI agents, not a bad idea indeed.
If done, I would vote for something shipped as source package or source generator or similar, trying to keep dependency chain small.
Sounds goo to me 👍🏻
There's a lot of samples of existing work, so shouldn't be impossible, performance is of course always a concern but maybe could utilize mixed-mode where usually done using .NET libraries and complex cases offload to another parser that might not be that fast (or support pre-compilation). |
|
Custom regex engine in the works 😆 sebastienros/jint#2380 |
|
Wow, that was fast! 😮 Now all we need is a QuickJS bytecode-to-IL converter, and we can finally ditch that unholy hack called RegExp to Regex conversion. 😄 |
|
Or, even better, Jint could generate IL instead of some custom bytecode to begin with. 🤔 The interpreter might be somewhat trickier that way, however Claude might be able to cobble up an IL interpreter tailored to the problem based on some existing implementations such as the CoreCLR IL interpreter or https://github.com/Ourpalm/ILRuntime. |
|
Yes, many possible venues to explore indeed. I'm on mobile now but I think at least v flag parsing was a problem. Need to check where the fix needs to go when back in front of keyboard... |
|
As a matter of fact, the set of regexps that can be converted to .NET Regexs so they produce results compliant to the ES spec is pretty small: https://github.com/adams85/acornima/?tab=readme-ov-file#regular-expressions Roughly, it's basic, case-sensitive, non-Unicode patterns. Beyond that, quirks start to appear. |
Summary
\p{Script=Latin}), Script_Extensions (\p{scx=Latn}), and Binary (\p{Alphabetic}) propertiesregexp-unicode-property-escapesconversion to .NETRegex, where previously only General Categories were convertible (Script/Binary causedConversionError)tools/UnicodeDataGenerator) to reproduce the data from Unicode consortium UCD filesPreviously, patterns like
\p{Script=Latin}or\p{Alphabetic}would pass validation but fail conversion with "Unsupported regular expression", because Acornima had no code point range data for these properties. This change embeds ~14K code point ranges (175 scripts × 2 for sc/scx + 50 binary properties) as static data, following the sameReadOnlySpan<int>pattern used byTokenizer.Helpers.Generated.cs.Special-case handling for
Any(trivial range),ASCII(trivial range), andAssigned(derived at runtime from .NET'sCharUnicodeInfoto match the runtime's Unicode version).Test plan
regexp-unicode-property-escapesfrom excluded features results in ~1300 newly passing tests (only Unicode version mismatch tests excluded individually)🤖 Generated with Claude Code